<?
/**
 * Helper_FormFree 表单的显示,数据的列表
 *
 * @copyright Copyright (c) 2007 - 2008 CWISs.com
 * @package Core
 * @author 叶腾飞 jufeis@gmail.com
 * @version 1.0
 */
class Helper_FormFree{
	
    /**
     * 元素的数据信息,通过::setElementData()进行设置,::tetElementData()访问
     * $elementData的格式
     * $elementData=array(
      				'lot_no' => array(
	      						'default' => array(
	      										'name'		=> 'lot_no',
	      										'lable' 	=> "Lot no",
	      										'inputType' => 'textbox',
	      										'allowBlank' => false,
	      										'blankText'  => 'Pls fill this filed',
	      									 	'active' => true,
	      						),
	      						'db'	=>array(
	      							'type' 		=> "varchar",
	      							'length' 	=> 20
	      						),
	      						'lister' 	=> array(
	      						),
	      						'creater'	=> array(
	      						),
	      						'updater'	=> array(
	      						), 
      				)
     * )
     * @var array
     * @access private
     */
	private $elementData = array();
	private $listData = array();
	
    //overloading function
    function __call($method, $args){
        return call_user_func_array(array($this->html, $method), $args);
    }

	function __construct(){
	}

	public function setElementData($data){
		if (!is_array($data)) {
			wrong("Element data must be array");
		}
		$this->elementData = $data;
	}

	public function setListData($list_data){
		if (!is_array($list_data)) {
			wrong("List data must be array");
		}
		$this->listData = $list_data;
	}
	/**
	 * According to the element defination,get one attribute.
	 * 
	 * @param string $element_name 
	 * @param string $type
	 * @param string $attrib
	 * @param mix	 $default
	 * 
	 * @return mix
	 * */
	private function getElementAttribute($element_name, $type, $attrib = null){
		
		// 1./  $elementdata[creater]	 ->  $elementdata[default]
		//      			 updater
		//					 lister 
		$ret = $this->elementData[$element_name]['default'];
		
		if(is_array($this->elementData[$element_name][$type])){
			foreach ($this->elementData[$element_name][$type] as $key => $value){
				$ret[$key] = $value;
			}
		}
		
		if ($attrib != null) {
			$ret = $ret[$attrib];
		}
		/*
		} else {
		
			if (isset($this->elementData[$element_name][$type][$attrib]) ) {
				$value = $this->elementData[$element_name][$type][$attrib];
			} else if (isset($this->elementData[$element_name]['default'][$attrib])) {
				$value = $this->elementData[$element_name]['default'][$attrib];
			} else {
				$value = null;
			}
		}*/
		return $ret;
	}
	/**
	 * get the fields we will use in all the types we specificated or any types we specificated.
	 * 
	 * @param  mix $types lister;creater;updater;db
	 * @param  string $relation all;any
	 * @param  string $retField   the returned value will be who's name properity
	 * 
	 * if $retField == null, this will returl the fields' name
	 * if $retField == 'creater', this will return the fields' name in 'creater' properity
	 * etc..
	 * 
	 * @return array
	 * 
	 * */
	public function getUsedFields($types,$relation, $retField=null){
		
		if (!is_array($types)) {
			$types = explode(',',$types);
		}
		
		$fields = array();
		
		foreach ( array_keys($this->elementData) as $name) {
			foreach ( $types as $type ) {
				$flag = $this->getElementAttribute($name,$type,"actived");
				
				if ($relation == 'all'){
						if ($flag === false) {
							$actived = false;
							break;
						} else {
							$actived = true;
						}
				} else if ($relation == 'any') {
						if ($flag !== false) {
							$actived = true;
							break;
						} else {
							$actived = false;
						}
				}
			}
			
			if ($actived != false) {
				
				if ($retField == null) {
					 $fields[] = $name;
				} else {
					 $fields[] = $this->getElementAttribute($name,$retField,"name");
				}
				
			} 
		}
		return $fields;
	}
	
	/**
	 * Get the form array
	 * @param string $type lister;creater;updater
	 * 
	 * @return array
	 * */
	public function getDisplayArray($type){
				
		$out = array();
		$out['girdHead'] = array();
		
		$out['FORM_INFO'] = $this->getElementAttribute('FORM_INFO', $type);
		

		$properities = $this->getAllAttributes($type,'FORM_INFO');
		$html_elements = array();
		
		foreach ($properities as $properity){
			
			if ($properity['active'] === false) {
				continue;
			} else {
				$html_elements[] = $properity;
				
				$girdHead = array(
						'header' => $properity['fieldLabel'],
						'dataIndex' => $properity['name'],
				);
				if ($properity['girdHead'] != true ) {
						$girdHead['hidden']	= true;
				};
				
				$out['girdHead'][] = $girdHead;
			}
		}

		$out['elements'] = $html_elements;
		/*
		
		'metaData': {
    totalProperty: 'listData.pager.total',
    root: 'listData.data',
    id: 'da_id',
	fields: ['da_id', 'lot_no', 'quantity_in']},
	
		*/
		switch ($type){
			case 'lister':
				$out['listData'] = &$this->listData;
				
				if(_gp('start','int') == 0){

					$fields = array();
					if (is_array($this->listData['data'][0])) {
						$fields=array_keys($this->listData['data'][0]);
					}

					$out['metaData'] = array(
						'totalProperty' => 'listData.pager.total',
						'root' => 'listData.data',
						'id' => $this->listData['cfg']['primaryKey'],
						'fields' => $fields
					);
				}
				break;	
			case 'creater':
				break;
				
		}
		return $out;
	}
	/**
	 * Display the form
	 * @param string $type lister;creater;updater
	 * 
	 * */
	public function display($type){
		$out = $this->getDisplayArray($type);
		$Json = new Helper_JSON();
		echo $Json->encode($out);
	}
	
	/**
	 * 
	 * According to the element defination,get all the attributes. 
	 * the element in the $except list will be excluded.
	 * 
	 * 
	 * @param string $type
	 * @param mix $except = ''
	 * 
	 * @return array
	 * 
	 * 
	 * 
	 * */
	public  function  getAllAttributes($type,$except= ''){
		//   $elementdata[creater]	 ->  $elementdata[default] ->not set
		//      		  updater
		//				  lister 		
		
		$ret = array();
		if (!is_array($except)) {
			$except = explode(',',$except);
		}
		foreach ($this->elementData as $name => $element) {
			if(in_array($name,$except)) continue;
			$ret[$name] = $element['default'];
			if(is_array($element[$type])){
				foreach ($element[$type] as $key => $value){
					$ret[$name][$key] = $value;
				}
			}
		}
		
		return $ret;
	}
	
	/**
	 * 获取搜索用的条件Sql语句
	 * 
	 * @param array $request 条件数组, 默认为_REQUEST数组
	 * 
	 * @return string
	 */
	public function getSearchConditionsSql($request = null,$tbname=null){
		if ($request == null) $request = $_REQUEST;
		$condition = array();
		
		$elements = $this->getAllAttributes('searcher'); 
		
		foreach ($elements as $element){
			$condition[] = self::phaseSearchCondition($element['name'],$request[$element['name']],$element['searchType'],$tbname);
		}
		$condition = array_diff($condition, array(''));
		
		if (count($condition) > 0){
			return ' and ' . join(' and ', $condition);
		} else {
			return "";
		}
	}
	
	/**
	 *  解析出搜索的条件
	 *	$type
	 *		= exact
	 *		= mix
	 *		= date
	 *		= region
	 *		= remark
	 * 
	 * 
	 * @param string $name 
	 * @param string $string
	 * @param string $type
	 * 
	 * @return string
	 */

	static function phaseSearchCondition($name,$condition,$type,$tbname=null){
		
		$field_name = $tbname == null ? "`$name`" : "`$tbname`.`$name`";

		//{{ to adapt the parameter name change
		$string = $condition;
		unset($condition);
		//}}
		
		if($string == '') return "";
		
		$conditions = explode(',',$string);
		
		if($type == 'exact' || $type == "mix") {
			foreach ($conditions as $condition){
				$condition = trim($condition);
				if(strpos($condition,'%') > -1){
					$condition_like[] = "$field_name like '$condition'";
				} else {
					$condition_exact[] = "'$condition'";
				}
				
			}
		}
		/*
		$type
			= exact
			= mix
			= date
			= region
			= remark
		*/
		switch ($type) {
			case "exact":
				$condition_e = @implode(',',$condition_exact);
				if($condition_e)
					$sql = "$field_name in ($condition_e)";
				break;
			case "mix":
				$condition_e = @implode(',',$condition_exact);
				$condition_l = @implode(' or ',$condition_like);
				if($condition_e)
					$sql[] = "$field_name in ($condition_e)";
				if($condition_l)
					$sql[] = "($condition_l)";
				$sql = implode(" or ", $sql);
				break;
			case "timestamp":
			case "date":			
				$now = date('Y-m-d H:i:s');
				
				$today = date("Y-m-d 00:00:00");
				$yesterday = date('Y-m-d 00:00:00',strtotime("-1 day")). "~".$today;
				
				//$this_week = date('Y-m-d',"-1 week");
				//$last_week = date('Y-m-d',"-1 week");
				
				$this_month = date('Y-m-01 00:00:00');
				$last_month = date('Y-m-01 00:00:00',strtotime("-1 month")) . "~" . $this_month;

				$keywords = array("now","today","yesterday","this month","last month");
				
				$replaces = array($now,$today,$yeaterday,$this_month,$last_month);
				
				foreach ($conditions as $condition){
					
					$condition = str_replace($keywords,$replaces,strtolower($condition));
					
					$date_array = explode('~',$condition);
					$date_array = _trimAll($date_array);
					
					unset($condition);
					
					if($date_array[0])
						$type == "timestamp" && $date_array[0] = strtotime($date_array[0]);
						$condition[] = "$field_name >= '$date_array[0]'";
					
					if($date_array[1])
						$type == "timestamp" && $date_array[1] = strtotime($date_array[1]);
						$condition[] = "$field_name <= '$date_array[1]'";
	
					$sql[] = "(" . implode(" and ", $condition) . ")";
					
				}
				$sql = implode(" or ", $sql);
				break;	
			case "region":
				foreach ($conditions as $condition){
					$keywords = array(">","<","~","=");
					//~ is found in condition string
					if( strpos($condition,"~") > -1 ){
						
						$data_array = explode('~',$string);
						
						unset($condition);
						if($data_array[0])
							$condition[] = "$field_name >= '$data_array[0]'";
						if($data_array[1])
							$condition[] = "$field_name <= '$data_array[1]'";
		
						$sql[] = "(" . implode(" and ", $condition) . ")";
						
					}else if(str_replace($keywords,"",$condition) != $condition){
						$sql[] = "$field_name$condition";
					}else {
						$sql[] = "$field_name = $condition";
					}
				}
				$sql = implode(" or ", $sql);
				break;
			case "remark":
				unset($condition_like);
				foreach ($conditions as $condition){
					$condition = trim($condition);
					$sql[] = "$field_name like '%$condition%'";
				}		
				$sql = implode(" or ", $sql);
				break;
		}
		return $sql;
	}
}
